import {
  BadRequestException,
  Inject,
  Injectable,
  Logger,
} from '@nestjs/common';
import { Like, Repository } from 'typeorm';
import { UserEntity } from './entities/user.entity';
import { RegisterDto } from './dtos/register.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { RedisService } from 'src/redis/redis.service';
import { md5 } from 'src/utils';
import { Role } from './entities/role.entity';
import { Permission } from './entities/permissions.entity';
import { LoginDto } from './dtos/login.dto';
import { UpdatePasswordDto } from './dtos/updatePassword.dto';
import { UpdateUserDto } from './dtos/updateUser.dto';
@Injectable()
export class UserService {
  private logger = new Logger();

  @InjectRepository(UserEntity)
  userRepository: Repository<UserEntity>;

  @Inject(RedisService)
  private redisService: RedisService;

  @InjectRepository(Role)
  private roleRepository: Repository<Role>;

  @InjectRepository(Permission)
  private permissionRepository: Repository<Permission>;
  // 初始化
  async initData() {
    const user1 = new UserEntity();
    user1.username = 'zhangsan';
    user1.password = md5('111111');
    user1.email = 'xxx@xx.com';
    user1.isAdmin = true;
    user1.nickName = '张三';
    user1.phoneNumber = '13233323333';

    const user2 = new UserEntity();
    user2.username = 'lisi';
    user2.password = md5('222222');
    user2.email = 'yy@yy.com';
    user2.nickName = '李四';

    const role1 = new Role();
    role1.name = '管理员';

    const role2 = new Role();
    role2.name = '普通用户';

    const permission1 = new Permission();
    permission1.code = 'ccc';
    permission1.description = '访问 ccc 接口';

    const permission2 = new Permission();
    permission2.code = 'ddd';
    permission2.description = '访问 ddd 接口';

    user1.roles = [role1];
    user2.roles = [role2];

    role1.permissions = [permission1, permission2];
    role2.permissions = [permission1];
    await this.permissionRepository.save([permission1, permission2]);
    await this.roleRepository.save([role1, role2]);
    await this.userRepository.save([user1, user2]);
  }
  // 注册
  async register(registerDto: RegisterDto) {
    const captcha = await this.redisService.get(`captcha_${registerDto.email}`);
    if (!captcha) {
      throw new BadRequestException('验证码已失效');
    }
    if (captcha !== registerDto.captcha) {
      throw new BadRequestException('验证码不正确');
    }
    const foundUser = await this.userRepository.findOneBy({
      username: registerDto.username,
    });
    if (foundUser) {
      throw new BadRequestException('用户已存在');
    }
    const user = new UserEntity();
    user.username = registerDto.username;
    user.password = md5(registerDto.password);
    user.email = registerDto.email;
    user.nickName = registerDto.nickName;
    try {
      await this.userRepository.save(user);
      return '注册成功';
    } catch (e) {
      this.logger.error(e, UserService);
      return '注册失败';
    }
  }
  // 登录
  async login(loginDto: LoginDto, isAdmin: boolean) {
    const user = await this.userRepository.findOne({
      where: {
        username: loginDto.username,
        isAdmin,
      },
      relations: ['roles', 'roles.permissions'],
    });
    if (!user) {
      throw new BadRequestException('用户不存在');
    }
    if (user.password !== md5(loginDto.password)) {
      throw new BadRequestException('密码错误');
    }
    // const vo = new LoginUserVo();
    // vo.userInfo = {
    //   id: user.id,
    //   username: user.username,
    //   nickName: user.nickName,
    //   email: user.email,
    //   phoneNumber: user.phoneNumber,
    //   headPic: user.headPic,
    //   createTime: user.createTime.getTime(),
    //   isFrozen: user.isFrozen,
    //   isAdmin: user.isAdmin,
    //   roles: user.roles.map((item) => item.name),
    //   permissions: user.roles.reduce((arr, item) => {
    //     item.permissions.forEach((permission) => {
    //       if (arr.indexOf(permission) === -1) {
    //         arr.push(permission);
    //       }
    //     });
    //     return arr;
    //   }, []),
    // };
    const returnUser = {
      ...user,
      roles: user.roles.map((item) => item.name),
      permissions: user.roles.reduce((arr, item) => {
        item.permissions.forEach((permission) => {
          if (arr.indexOf(permission) === -1) {
            arr.push(permission);
          }
        });
        return arr;
      }, []),
    };
    return returnUser;
  }
  // 根据id查询用户
  async findUserById(id: number, isAdmin: boolean) {
    const user = await this.userRepository.findOne({
      where: {
        id,
        isAdmin,
      },
      relations: ['roles', 'roles.permissions'],
    });
    if (!user) {
      throw new BadRequestException('用户未找到');
    }
    return {
      id: user.id,
      username: user.username,
      email: user.email,
      nickName: user.nickName,
      headPic: user.headPic,
      phoneNumber: user.phoneNumber,
      isFrozen: user.isFrozen,
      isAdmin: user.isAdmin,
      createTime: user.createTime.getTime(),
      roles: user.roles.map((item) => item.name),
      permissions: user.roles.reduce((arr, item) => {
        item.permissions.forEach((v) => {
          if (arr.indexOf(v) === -1) {
            arr.push(v);
          }
        });
        return arr;
      }, []),
    };
  }
  // 修改密码
  async updatePassword(updatePasswordDto: UpdatePasswordDto) {
    const captcha = await this.redisService.get(
      `updatePassword_${updatePasswordDto.email}`,
    );
    if (!captcha) {
      throw new BadRequestException('验证码已过期');
    }
    if (captcha !== updatePasswordDto.captcha) {
      throw new BadRequestException('验证码错误');
    }
    const foundUser = await this.userRepository.findOneBy({
      username: updatePasswordDto.username,
    });
    console.log(updatePasswordDto.email, 'up');
    console.log(foundUser.email, 'this');
    if (updatePasswordDto.email !== foundUser.email) {
      throw new BadRequestException('邮箱账号不一致');
    }
    foundUser.password = md5(updatePasswordDto.password);
    try {
      await this.userRepository.save(foundUser);
      return '修改成功';
    } catch (e) {
      this.logger.error(e, UserService);
      return '修改失败';
    }
  }
  // 修改个人信息
  async updateUser(userId: number, updateUserDto: UpdateUserDto) {
    const captcha = await this.redisService.get(
      `updateUser_${updateUserDto.email}`,
    );
    if (!captcha) {
      throw new BadRequestException('验证码已过期');
    }
    if (captcha !== updateUserDto.captcha) {
      throw new BadRequestException('验证码错误');
    }
    const foundUser = await this.userRepository.findOneBy({
      id: userId,
    });
    if (updateUserDto.nickName) {
      foundUser.nickName = updateUserDto.nickName;
    }
    if (updateUserDto.headPic) {
      foundUser.headPic = updateUserDto.headPic;
    }
    try {
      await this.userRepository.save(foundUser);
      return '修改成功';
    } catch (e) {
      this.logger.error(e, UserService);
      return '修改失败';
    }
  }
  //冻结用户
  async freezeUserById(id: number) {
    const user = await this.userRepository.findOneBy({
      id,
    });
    user.isFrozen = true;
    await this.userRepository.save(user);
  }
  // 用户列表
  async findList(
    pageNo: number,
    pageSize: number,
    username: string,
    nickName: string,
    email: string,
  ) {
    const skipNumber = (pageNo - 1) * pageSize;
    const condition: Record<string, any> = {};
    if (username) {
      condition.username = Like(`%${username}%`);
    }
    if (nickName) {
      condition.nickName = Like(`%${nickName}%`);
    }
    if (email) {
      condition.email = Like(`%${email}%`);
    }
    const [users, totalCount] = await this.userRepository.findAndCount({
      select: [
        'id',
        'username',
        'nickName',
        'headPic',
        'email',
        'phoneNumber',
        'isFrozen',
        'createTime',
      ],
      skip: skipNumber,
      take: pageSize,
      where: condition,
    });
    return {
      users,
      totalCount,
    };
  }
}
